package com.skytech.component.crawler.scratch.chrome;

import com.skytech.component.crawler.scratch.base.CrawlerUrl;
import com.skytech.component.crawler.scratch.base.CrawlerUrlDAO;
import com.skytech.component.crawler.scratch.base.CreatePageType;
import com.skytech.component.crawler.scratch.base.TargetRules;
import com.skytech.component.crawler.util.ElementAbstractUrl;
import com.skytech.component.crawler.util.ListRegex;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Example;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class SingleChromeTask {
    @Value("${chrome.driver.path}")
    public String driverPath;

    List<String> contentLast = null;

    private static final Logger log = LoggerFactory.getLogger(SingleChromeTask.class);



    @Async
    public void start(List<TargetRules> targetRuleList, CrawlerUrlDAO crawlerUrlDAO) {
        for (TargetRules targetRules : targetRuleList) {
            DesiredCapabilities capabilities=new DesiredCapabilities();
            ChromeOptions options = new ChromeOptions();
            options.setExperimentalOption("androidProcess", "com.tencent.mm:tools");
            capabilities.setCapability(ChromeOptions.CAPABILITY, options);
            System.setProperty("webdriver.chrome.driver", driverPath);
            ChromeDriver driver = new ChromeDriver();
            try {
                driver.get(targetRules.getSeedUrl());
                contentLast = null;
                driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
                partClickNext(driver, targetRules, crawlerUrlDAO);
            } catch (Exception e) {
                log.error("{}--超时--{}", targetRules.getId(), e.getMessage());
            }finally {
                driver.quit();
            }
        }

    }

    public void partClickNext(ChromeDriver driver, TargetRules targetRules, CrawlerUrlDAO crawlerUrlDAO) {
        String html = driver.findElementByTagName("html").getAttribute("outerHTML");

        Document parse = Jsoup.parse(html, driver.getCurrentUrl());
        Elements allElements = parse.getAllElements();
        List<String> content = new ArrayList<>();
        if (!StringUtils.isEmpty(targetRules.getContentRegex())) {
            content = ListRegex.regex(ElementAbstractUrl.links(allElements), targetRules.getContentRegex());
        } else if (!StringUtils.isEmpty(targetRules.getContentElement())) {
            Elements elements = allElements.select(targetRules.getContentElement());
            if (!elements.isEmpty()) {
                content = ElementAbstractUrl.links(elements.get(0).getAllElements());
            }
        } else {
            return;
        }
        CrawlerUrl crawlerUrl = new CrawlerUrl();
        int i = 0;
        for (String contentUrl : content) {
            i++;
            crawlerUrl.setContentUrl(contentUrl);
            if (!crawlerUrlDAO.findAll(Example.of(crawlerUrl)).isEmpty()) {
                continue;
            }
            CrawlerUrl c = new CrawlerUrl();
            c.setId(UUID.randomUUID().toString());
            c.setContentUrl(contentUrl);
            c.setDomainUrl(driver.getCurrentUrl());
            c.setRuleId(targetRules.getId());
            c.setParse("no");
            c.setOperateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            crawlerUrlDAO.save(c);
        }
        String currentPath = driver.getCurrentUrl();
        try {
            if (StringUtils.isEmpty(targetRules.getNextButton())) {
                log.debug("{}-没有配置翻页", targetRules.getNextButton());
                return;
            }

            WebElement element = driver.findElementByXPath(targetRules.getNextButton());

            log.info("按钮连接{}", element.getAttribute("href"));
            log.info("当前页面{}", driver.getCurrentUrl());
            if (!CreatePageType.url_unchanged.toString().equals(targetRules.getType()) && driver.getCurrentUrl().equals(element.getAttribute("href"))) {
                //如果两次点击的页面相同停止当前任务
                log.error("{}两次链接地址相同,当前页{}，下一页{}", targetRules.getId(), driver.getCurrentUrl(), element.getAttribute("href"));
                return;
            }
            if (CreatePageType.url_unchanged.toString().equals(targetRules.getType())) {
                if (contentLast != null && content.size() != 0) {
                    if (contentLast.equals(content)) {
                        log.error("{}两次链接内容相同,当前页{}，下一页{}", targetRules.getId(), driver.getCurrentUrl(), element.getAttribute("href"));
                        return;
                    }
                }
                contentLast = content;
            }
            element.click();
            if(CreatePageType.url_unchanged.toString().equals(targetRules.getType())){
                Thread.sleep(3000);
            }
        } catch (Exception e) {
            log.error("{}点击下一页出现问题{}", targetRules.getId(), e.getMessage());
            return;
        }
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        String nextPath = driver.getCurrentUrl();
        if (!CreatePageType.url_unchanged.toString().equals(targetRules.getType()) && currentPath.equals(nextPath)) {
            //点击
            log.error("{}点击方法,当前页{}，下一页{}", targetRules.getId(), currentPath, nextPath);
            return;
        }


        partClickNext(driver, targetRules, crawlerUrlDAO);

    }

}
